/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package matematikapirma.math;

import java.util.ArrayList;
import java.util.List;
import matematikapirma.CurveAlgorithm;
import matematikapirma.Point;

/**
 *
 * @author Tadas
 */
public class BezierCurveAlgorithm implements CurveAlgorithm {

    public List<Point> calculatePoints(List<Point> initialPoints, boolean open, int steps, int start, int end) {
        List<Point> points = new ArrayList<Point>();
        points.addAll(initialPoints);

        List<Point> rpoints = new ArrayList<Point>();

        for (double u = 0.0; u < 1.0; u += 0.005) {
            rpoints.add(BezierPoint(points, points.size() - 1, u));
        }

        rpoints.add(BezierPoint(points, points.size() - 1, 1.0));


        return rpoints;
    }

    protected double[] allBernstein(int n, double u) {
        double[] B = new double[n + 1];
        B[0] = 1.0;
        double u1 = 1.0 - u;
        for (int j = 1; j <= n; j++) {
            double saved = 0.0;
            for (int k = 0; k < j; k++) {
                double temp = B[k];
                B[k] = saved + u1 * temp;
                saved = u * temp;
            }
            B[j] = saved;

        }
        return B;
    }

    protected Point BezierPoint(List<Point> points, int n, double u) {
        double[] B = allBernstein(n, u);
        Point C = points.get(0).dot(0.0);

        double W = 0.0;
        for (int k = 0; k <= n; k++) {
            C = C.add(points.get(k).dot(B[k]).dot(points.get(k).getWeight()));
            W += B[k] * points.get(k).getWeight();
        }
        return C.dot(1.0 / W);
    }

    @Override
    public String toString(){
        return "Bezier";
    }
}
